package mem

import (
	"sync"
)

//循环队列
type RingBuffer struct {
	rwm sync.RWMutex
	buf []any
	pos int
}

func NewRingBuffer(size int) *RingBuffer {
	if size < 1 {
		size = 1
	}
	return &RingBuffer{
		buf: make([]any, size),
		pos: 0,
	}
}

func (b *RingBuffer) Len() int {
	return len(b.buf)
}

func (b *RingBuffer) Set(v any) {
	b.rwm.Lock()
	defer b.rwm.Unlock()
	b.buf[b.pos] = v
	b.pos++
	if b.pos == b.Len() {
		b.pos = 0
	}
}

func (b *RingBuffer) Range(f func(any) error) error {
	b.rwm.RLock()
	defer b.rwm.RUnlock()
	e := b.rangeData(b.pos, len(b.buf), f)
	if e != nil {
		return e
	}
	return b.rangeData(0, b.pos, f)
}

func (b *RingBuffer) rangeData(i, n int, f func(any) error) error {
	for i < n {
		e := f(b.buf[i])
		if e != nil {
			return e
		}
		i++
	}
	return nil
}
